/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <向量.h>
#include <矩阵.h>
#include <vector>
//using namespace std;
 
class C_几何数据变换 {
	float32 m_Matrix[16];

public:
	C_几何数据变换();
	C_几何数据变换(const float32* mat) {
		memcpy(m_Matrix, mat, sizeof(float32) * 16);
	}
	~C_几何数据变换();

	inline void f_重置() { Matrix4X4f_Identity(m_Matrix); }
	inline const float32* f_getMartix()const { return m_Matrix; }
	operator Mat44f& () {
		return *(Mat44f*)m_Matrix;
	}

	C_几何数据变换& f_RX(float32 角度);
	C_几何数据变换&  f_RY(float32 角度);
	C_几何数据变换&  f_RZ(float32 角度);

	C_几何数据变换&  f_MX(float32 m);
	C_几何数据变换&  f_MY(float32 m);
	C_几何数据变换&  f_MZ(float32 m);
	C_几何数据变换&  f_MXYZ(const float32 m[3]);

	C_几何数据变换&  f_SX(float32 s);
	C_几何数据变换&  f_SY(float32 s);
	C_几何数据变换&  f_SZ(float32 s);
	C_几何数据变换&  f_SXYZ(const vec3& s);

	C_几何数据变换& operator *= (const float32* mat);
	Mat44f operator * (const Mat44f& mat);


	void operator = (const Mat44f& mat) {
		*((Mat44f*)m_Matrix) = mat;
	}

	void operator>>(std::vector<vec3>& vert) {
		for (auto& vec : vert) {
			operator>>(&vec);
		}
	}
	void operator>>(vec3* vert) {
		auto& v = *vert;
		vec4 tmpV = { v.x, v.y, v.z, 1.0 };
		vec4 newV = { 0.0,0.0,0.0,0.0 };
		Mat变换坐标4(m_Matrix, (float32*)&tmpV, (float32*)&newV);

		v.x = newV.x;
		v.y = newV.y;
		v.z = newV.z;
	}
	vec3 operator<<(const vec3& vert) {
		vec4 tmpV = { vert.x, vert.y, vert.z, 1.0 };
		vec4 newV = { 0.0,0.0,0.0,0.0 };
		Mat变换坐标4(m_Matrix, (float32*)&tmpV, (float32*)&newV);

		return { newV.x, newV.y, newV.z };
	}

	void operator>>(Mat44f* mat) { memcpy(mat, m_Matrix, sizeof(float32)*16); }

	vec3 f_Euler();

	void f_变换(std::vector<vec3>& vert, ui2_32 range);

	void f_变换(E_vec3元素指针* re, const E_vec3元素指针& e);
	void f_变换(E_vec3元素指针* re, const std::vector<vec3>& vert);

	static void f_正交投影(const vec4& view, float32* mat);

	void f_Invert(const float32* mat);

};


class C_Quaternion
{
	float32	m_X;
	float32	m_Y;
	float32	m_Z;
	float32	m_W;
	friend	C_Quaternion;

public:
	C_Quaternion();
	~C_Quaternion();

	C_Quaternion(vec4 q) {
		m_X = q.x; m_Y = q.y; m_Z = q.z; m_W = q.w;
	}

	void f_FromAxis(vec3 v, float32 angle);
	void f_FromDir(vec3 dir);

	inline C_Quaternion operator*= (const C_Quaternion& q) const {
		return C_Quaternion({ m_W*q.m_X + m_X*q.m_W + m_Y*q.m_Z + m_Z*q.m_Y,
							m_W*q.m_Y + m_Y*q.m_W + m_Z*q.m_X - m_X*q.m_Z,
							m_W*q.m_Z + m_Z*q.m_W + m_X*q.m_Y - m_Y*q.m_X,
							m_W*q.m_W - m_X*q.m_X - m_Y*q.m_Y - m_Z*q.m_Z
		});
	}

	Mat44f f_getMar4X4() const;

private:


};

